package strings

import (
	"fmt"
	"math/rand"
	"regexp"
	"strconv"
	"strings"
	"time"
	"unicode"
)

func After(s, after string) string {
	index := strings.Index(s, after)
	if index == -1 {
		return ""
	}
	return s[index+len(after):]
}

func Before(s, before string) string {
	index := strings.Index(s, before)
	if index == -1 {
		return s
	}
	return s[:index]
}

func Replace(search, replace, subject string) string {
	return strings.Replace(subject, search, replace, -1)
}

func Repeat(s string, n int) string {
	result := ""
	for i := 0; i < n; i++ {
		result += s
	}
	return result
}

func Pad(s string, length int, pad string) string {
	if len(s) >= length {
		return s
	}
	diff := length - len(s)
	halfDiff := diff / 2
	leftPad := strings.Repeat(pad, halfDiff)
	rightPad := strings.Repeat(pad, diff-halfDiff)
	return leftPad + s + rightPad
}

func Slug(s string) string {
	s = strings.ToLower(s)
	re := regexp.MustCompile(`[^a-z0-9]+`)
	return strings.Trim(re.ReplaceAllString(s, "-"), "-")
}

// Plural 单词转复数
func Plural(s string) string {
	if strings.HasSuffix(s, "s") || strings.HasSuffix(s, "x") || strings.HasSuffix(s, "z") || strings.HasSuffix(s, "ch") || strings.HasSuffix(s, "sh") {
		return s + "es"
	}
	return s + "s"
}

// Singular 复数转单数
func Singular(s string) string {
	if strings.HasSuffix(s, "es") {
		if strings.HasSuffix(s[:len(s)-2], "s") || strings.HasSuffix(s[:len(s)-2], "x") || strings.HasSuffix(s[:len(s)-2], "z") || strings.HasSuffix(s[:len(s)-2], "ch") || strings.HasSuffix(s[:len(s)-2], "sh") {
			return s[:len(s)-2]
		}
	}
	if strings.HasSuffix(s, "s") {
		return s[:len(s)-1]
	}
	return s
}

func Reverse(s string) string {
	runes := []rune(s)
	for i, j := 0, len(runes)-1; i < j; i, j = i+1, j-1 {
		runes[i], runes[j] = runes[j], runes[i]
	}
	return string(runes)
}

func Substr(s string, start int, length int) string {
	end := start + length
	if end > len(s) {
		end = len(s)
	}
	if start < 0 || start >= len(s) {
		return ""
	}
	return s[start:end]
}

func Shuffle(s string) string {
	runes := []rune(s)
	rand.NewSource(time.Now().UnixNano())
	rand.Shuffle(len(runes), func(i, j int) {
		runes[i], runes[j] = runes[j], runes[i]
	})
	return string(runes)
}

// Title 将字符串转换为首字母大写的标题格式
func Title(s string) string {
	words := strings.Fields(s)
	result := ""
	for _, word := range words {
		if len(word) > 0 {
			firstChar := strings.ToUpper(string(word[0]))
			rest := word[1:]
			result += firstChar + rest + " "
		}
	}
	return strings.TrimSpace(result)
}

func Truncate(s string, length int) string {
	if len(s) <= length {
		return s
	}
	return s[:length-3] + "..."
}

// Ucwords 将字符串中每个单词的首字母大写
func Ucwords(s string) string {
	words := strings.Fields(s)
	result := ""
	for _, word := range words {
		if len(word) > 0 {
			firstChar := strings.ToUpper(string(word[0]))
			rest := word[1:]
			result += firstChar + rest + " "
		}
	}
	return strings.TrimSpace(result)
}

func Camel2Snake(s string) string {
	var output []rune
	for i, r := range s {
		if i == 0 {
			output = append(output, unicode.ToLower(r))
		} else {
			if unicode.IsUpper(r) {
				output = append(output, '_')
			}
			output = append(output, unicode.ToLower(r))
		}
	}
	return string(output)
}

func Snake2Camel(s string) string {
	parts := strings.Split(s, "_")
	var camel string
	for i, part := range parts {
		if i == 0 {
			camel += part
		} else {
			firstChar := strings.ToUpper(string(part[0]))
			rest := part[1:]
			camel += firstChar + rest
		}
	}
	return camel
}

// StudlyCase StudlyCaps
func StudlyCase(s string) string {
	words := strings.FieldsFunc(s, func(r rune) bool { return r == '-' || r == '_' || r == ' ' })
	result := ""
	for _, word := range words {
		if len(word) > 0 {
			firstChar := strings.ToUpper(string(word[0]))
			rest := word[1:]
			result += firstChar + rest
		}
	}
	return result
}

// CamelCase lowerCamelCase
func CamelCase(s string) string {
	words := strings.FieldsFunc(s, func(r rune) bool { return r == '-' || r == '_' || r == ' ' })
	result := ""
	for i, word := range words {
		if i == 0 {
			result += strings.ToLower(word)
		} else {
			firstChar := strings.ToUpper(string(word[0]))
			rest := word[1:]
			result += firstChar + rest
		}
	}
	return result
}

// UpperSnakeCase UPPER_SNAKE_CASE
func UpperSnakeCase(s string) string {
	s = strings.ToUpper(s)
	re := regexp.MustCompile(`[^A-Z]+`)
	return strings.Trim(re.ReplaceAllString(s, "_"), "_")
}

func LowerFirst(s string) string {
	if len(s) == 0 {
		return s
	}
	firstChar := strings.ToLower(string(s[0]))
	return firstChar + s[1:]
}

func UpperFirst(s string) string {
	if len(s) == 0 {
		return s
	}
	firstChar := strings.ToUpper(string(s[0]))
	return firstChar + s[1:]
}

// ParseCapacity 解析存储容量字符串为字节数
func ParseCapacity(capacity string) (int64, error) {
	// 定义正则表达式匹配数字和单位
	re := regexp.MustCompile(`^(\d+)([KMGT]?B?)$`)
	matches := re.FindStringSubmatch(capacity)
	if len(matches) != 3 {
		return 0, fmt.Errorf("无效的容量格式: %s", capacity)
	}
	// 提取数字部分
	num, err := strconv.ParseInt(matches[1], 10, 64)
	if err != nil {
		return 0, fmt.Errorf("解析数字部分出错: %w", err)
	}
	// 提取单位部分
	unit := matches[2]
	switch unit {
	case "B":
		return num, nil
	case "KB", "K":
		return num * 1024, nil
	case "MB", "M":
		return num * 1024 * 1024, nil
	case "GB", "G":
		return num * 1024 * 1024 * 1024, nil
	case "TB", "T":
		return num * 1024 * 1024 * 1024 * 1024, nil
	default:
		return 0, fmt.Errorf("未知的容量单位: %s", unit)
	}
}
